package com.heima.wemedia.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.wemedia.listener.WmSensitiveDataListener;
import com.heima.wemedia.mapper.SensitiveMapper;
import com.heima.wemedia.service.ISensitiveService;
import com.heima.model.admin.dtos.SensitiveDto;
import com.heima.model.wemedia.pojos.WmSensitive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;

@RequiredArgsConstructor
@Service
@Slf4j
public class SensitiveImpl extends ServiceImpl<SensitiveMapper, WmSensitive> implements ISensitiveService {

    private final SensitiveMapper sensitiveMapper;

    private final RedisTemplate redisTemplate;

    @Override
    public PageResponseResult pageList(SensitiveDto dto) {
        // 分页条件判断
        dto.checkParam();

        /* 1. 在 redis 中进行查询, 如果存在数据则进行返回 */
        List sensitiveList = redisTemplate.opsForList().range("sensitive", 0, -1);
        /* 设置 使用 redis 所返回的 page 的下标 */
        Integer currPage = dto.getPage();
        int startIndex = (currPage - 1) * dto.getSize();  // 开始下标
        int endIndex = currPage * dto.getSize() -1 ;  // 结束下标

        /* 出现首次越界的情况 */
        if (endIndex > sensitiveList.size() - 1 && startIndex <= sensitiveList.size() - 1) {
            endIndex = sensitiveList.size() - 1;
            log.info("开始下标{} 结束下标{}", startIndex, endIndex);
        }else if (startIndex > sensitiveList.size()) { /* 当继续越界 */
            return null;
        }

        /* 构建分页数据 */
        if (!CollectionUtils.isEmpty(sensitiveList)) {  // 表示 redis 中存在数据
            PageResponseResult pageResponseResult = new PageResponseResult();
            pageResponseResult.setCurrentPage(dto.getPage());  // 设置当前页数
            pageResponseResult.setSize(dto.getSize());  // 设置分页大小
            pageResponseResult.setTotal(sensitiveList.size());  // 设置总条数
            pageResponseResult.setData(sensitiveList.subList(startIndex, endIndex));  // 设置 data 数据
            return pageResponseResult;
        }

        /* 2. redis 没有数据的情况下, 则在数据库中进行查询 */
        IPage page = new Page(dto.getPage(), dto.getSize());
        // 构造查询条件
        LambdaQueryWrapper<WmSensitive> queryWrapper = new LambdaQueryWrapper<>();
        // 敏感词名字模糊查询
        queryWrapper.like(dto.getName() != null, WmSensitive::getSensitives, dto.getName());
        // 时间降序排序
        queryWrapper.orderByDesc(WmSensitive::getCreatedTime);
        super.page(page, queryWrapper);

        if (page.getRecords().size() == 0) {
            return null;
        }
        PageResponseResult result = new PageResponseResult();
        log.info("分页:{},{},{}", dto.getPage(), dto.getSize(), (int) page.getTotal());
        result.setCurrentPage(dto.getPage());
        result.setData(page.getRecords());
        result.setSize(dto.getSize());
        result.setTotal((int) page.getTotal());

        /* 3. 如果 redis 中没有数据, 则需要将 mysql 中所查询的数据写入 redis 中 */
        List<WmSensitive> wmSensitiveList = sensitiveMapper.selectList(new LambdaQueryWrapper<>());
        for (WmSensitive wmSensitive : wmSensitiveList) {
            redisTemplate.opsForList().rightPush("sensitive", wmSensitive);
        }

        return result;
    }

    @Override
    public void excelImport(MultipartFile file) {
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            log.error("文件上传失败{}", e);
        }

        EasyExcel.read(inputStream, WmSensitive.class, new WmSensitiveDataListener(this)).sheet().doRead();

    }

    @Override
    public void excelExport(String filePath) {
        /* 获取关键字列表 */
        List<WmSensitive> wmSensitiveList = sensitiveMapper.selectList(new LambdaQueryWrapper<>());

        FileOutputStream fileOutputStream;
        try {
            fileOutputStream = new FileOutputStream(new File(filePath));
        } catch (FileNotFoundException e) {
            log.error("文件创建失败");
            return;
        }

        EasyExcel.write(fileOutputStream, WmSensitive.class)
                .sheet("sheet1")
                .doWrite(() -> {
                    // 分页查询数据
                    return wmSensitiveList;
                });

    }

}
